using System;
using System.Collections.Generic;
using Generator.Model;

namespace Generator.Renderer.Public;

internal static class CallbackDelegate
{
    public static string Render(GirModel.Callback callback)
    {
        try
        {
            //We use the internal parameter expression function as for callbacks the data must
            //not be transferred to native, but to the managed world.
            var parameters = Internal.ParameterToManagedExpression.Initialize(callback.Parameters);

            return $@"
using System;
using System.Runtime.InteropServices;

#nullable enable

namespace {Namespace.GetPublicName(callback.Namespace)};

// AUTOGENERATED FILE - DO NOT MODIFY

public delegate {ReturnTypeRendererCallback.Render(callback.ReturnType)} {callback.Name}({RenderParameters(parameters)});";
        }
        catch (Exception ex)
        {
            Log.Warning($"Did not generate callback delegate {callback.Name}: {ex.Message}");

            return string.Empty;
        }
    }

    private static string RenderParameters(IEnumerable<Internal.ParameterToManagedData> parameters)
    {
        var result = new List<string>();
        foreach (var parameter in parameters)
        {
            if (parameter.IsCallbackUserData)
                continue;

            if (parameter.IsArrayLengthParameter)
                continue;

            if (parameter.IsGLibErrorParameter)
                continue;

            var name = Model.Parameter.GetName(parameter.Parameter);
            var typeData = ParameterRenderer.Render(parameter.Parameter);
            result.Add($"{typeData.Direction}{typeData.NullableTypeName} {name}");
        }

        return result.Join(", ");
    }
}
